unit u_player;

interface

uses u_mesh,     
    Microsoft.DirectX,
    Microsoft.DirectX.Direct3D,
    sysutils,
    Microsoft.DirectX.Direct3DX,
    u_astar,
    u_resennemi,
    u_chatform,
    u_jresau,
    u_partic,
    u_sound,
    u_ia,
    u_timer,
    u_load,
    u_server;

type

  t_montedescend = record
    x,y : integer;
    monte,descend : boolean;
  end;

  t_carac = record
    init: integer;
    stuff: integer;
    actuel: integer;
    emplacement_libre: integer;
  end;

  t_carac_player = record
    niveau: t_carac;
    vie: t_carac;
    xp: t_carac;
    force: t_carac;
    discretion: t_carac;
    degats: t_carac;
    portee: t_carac;
    armure: t_carac;
    vitesse: t_carac;
    taille: t_carac;
  end;

  sel = record
    x,y,posi,posj,id : integer;
    exist : boolean;
    t: string;
  end;

  c_player = class
    private
      player_y : integer;
      player_x : integer;
      //Les champs pour le resau :
      isconnected : boolean;
      vie : integer;//pour le test

      etage_actif : integer;
      is_loaded : boolean;
      next_step : integer;
      host_ : string;
      tiny_pas : c_sound;
      tiny_hit : c_sound;
      tiny_hitted : c_sound;
    public           
      map_name : string;
      clientorserveur : c_server;
      timer    : C_timer;
      attaque  : C_timer;
      etage : integer;
      mychat : c_chat;
      game_type : char;
      player_mesh : Mesh;
      player_texture : Texture;
      selection_pos : sel;
      carac: t_carac_player;
      texture_titou : texture;
      texture_clad : Texture;
      texture_xoy : Texture;
      texture_mouton : Texture;
//      porte : integer;  // pour le test
//      force : integer;  // pour le test
      myreseau : c_res_joueur;
      myreseauennemis : c_res_ennemi;
      dep: boolean;
      arrive: boolean;
      tab_contenu: t_tab_cont;
      pseudo_: string;
      myastar : c_astar;
      particle : tparticle;
      prout_etage : t_montedescend;
      //Pour tous les modes c'est gore mais bon!
      constructor create(s_or_c_or_o : char ; pseudo : string;host_or_map: string);
      procedure load_player(dev_ : device);
      procedure get_coord(var x_ : integer;var y_ : integer);
      procedure render_player(form_dev : Device);
      procedure calcul_astar(to_x, to_y : integer);
      function get_x : integer;
      function get_y : integer;
      procedure player_avance;
      procedure connection;
      procedure send_message(msg_ : string);
      procedure selection(x,y : integer; t : string;var  map : t_map_obj);
      procedure kill(var mouton : t_map ;var map : t_map_obj ;var mechant : t_tabennemi);
      procedure suicide(force,x,y,px,py : integer);
      procedure init_obj_carac;
      procedure gestion_catac;
      procedure update_equip_obj(posi: integer);
      procedure update_desequip_obj(posi: integer);
      procedure init(dev : device);
  end;

implementation

uses
  u_engine,
  u_menu_in_game;


  procedure c_player.init(dev : device);
  begin
    self.particle:= tparticle.Create(dev);
  end;



  procedure c_player.suicide(force : integer ; x,y,px,py : integer);
  begin
    tiny_hitted.play;
    self.vie := self.vie - 0;
    if self.vie < 1 then
      begin

        self.player_y := 10;
        self.player_x := 10;
      end;
    if self.game_type = 's' then
      begin
        clientorserveur.send_joueur_hit(inttostr(x),inttostr(y),inttostr(self.etage),inttostr(px),inttostr(py),inttostr(self.etage),inttostr(0));
      end;
  end;


//modif

  procedure c_player.kill(var mouton : t_map;var map: t_map_obj ;var mechant : t_tabennemi);
  var
    coord_ennemi : r_ennemi;
    i : integer;
  begin
    tiny_hit.play;
    if not (myplayer.game_type = 'c') then
      begin
        if myplayer.game_type = 's' then
          myplayer.clientorserveur.send_joueur_hit(IntToStr(player_x),
                                                   IntToStr(player_y),
                                                   IntToStr(etage),
                                                   IntToStr(mechant[myplayer.selection_pos.posj].emplacement.x),
                                                   IntToStr(mechant[myplayer.selection_pos.posj].emplacement.y),
                                                   IntToStr(etage), '0');

        myplayer.particle.add_part_player(100,myplayer.get_x,myplayer.get_y,mechant[myplayer.selection_pos.posj].emplacement.x,mechant[myplayer.selection_pos.posj].emplacement.y);
        mechant[self.selection_pos.posj].vie.actuel := mechant[self.selection_pos.posj].vie.actuel - 20;

        //self.particle.add_part(500,self.player_x,self.player_x,self.selection_pos.x,self.selection_pos.y);
        if mechant[self.selection_pos.posj].vie.actuel < 1 then
          begin
            mouton[0,mechant[myplayer.selection_pos.posj].emplacement.x,mechant[myplayer.selection_pos.posj].emplacement.y]._type := 'none';
            mouton[0,mechant[myplayer.selection_pos.posj].emplacement.x,mechant[myplayer.selection_pos.posj].emplacement.y].nom := 'none';
            map[0][self.selection_pos.posi].tab_etage[self.selection_pos.posj] := map[0][self.selection_pos.posi].tab_etage[high(map[0][self.selection_pos.posi].tab_etage)];
            mechant[self.selection_pos.posj] := mechant[high(mechant)];
            mechant[self.selection_pos.posj].posj := self.selection_pos.posj;
            setlength(map[0][self.selection_pos.posi].tab_etage,length(map[0][self.selection_pos.posi].tab_etage)-1);
            setlength(mechant,length(mechant)-1);
            self.selection_pos.exist := false;
            if myplayer.game_type = 's' then
              myplayer.clientorserveur.send_ennemi_del_pos(inttostr(selection_pos.x), inttostr(selection_pos.y), inttostr(etage));
          end;
      end
    else
      begin
        coord_ennemi := myreseauennemis.id_to_coord(selection_pos.id);                                                                                                       //Changer
        //Changer les dégats
        myplayer.clientorserveur.send_hitennemi(IntToStr(player_x), IntToStr(player_y), IntToStr(etage), IntToStr(coord_ennemi.x), IntToStr(coord_ennemi.y), IntToStr(etage), IntToStr(0));
      end;
  end;


  procedure c_player.selection(x: Integer; y: Integer; t : string;var map : t_map_obj);
    var
      i,j : integer;
    begin
      if not (myplayer.game_type = 'c') then
        begin
        selection_pos.x := x;
        selection_pos.y := y;
        selection_pos.exist := true;
        selection_pos.t := t;
        for i := low(map[0]) to high(map[0]) do
          begin
            for j := low(map[0][i].tab_etage) to high(map[0][i].tab_etage) do
              begin
                if (map[0][i].tab_etage[j].x = x) and (map[0][i].tab_etage[j].y = y)then
                  begin
                    self.selection_pos.posi := i;
                    self.selection_pos.posj := j;
                  end;
              end;
          end;
        end
      else
        begin
          selection_pos.x := x;
          selection_pos.y := y;
          selection_pos.id := myplayer.myreseauennemis.coord_to_id(x,y,myplayer.etage);
          selection_pos.exist := true;
          selection_pos.t := t;
        end;
      end;

  procedure c_player.connection;
    begin
      if game_type = 's' then
        begin
          clientorserveur := C_server.create;
          clientorserveur.connectserver(4545, pseudo_, map_name);
          myreseau := c_res_joueur.create;
        end
        else
        if game_type = 'c' then
          begin
            myreseau := c_res_joueur.create;
            clientorserveur := C_server.create;
            clientorserveur.connectclient(4545, host_, pseudo_);
            mymesh := c_mesh.create('titoujtecul.tmp', game_type);
            mymesh.loader_mesh(myform._3D_device, mymesh.dep_eta.etage);
            myastar := C_astar.create;
            mymenu_in_game := c_menu_in_game.create(myform._3D_device, myplayer.carac, myplayer.tab_contenu, mymenu.player_name);
          end;
    end;

  constructor c_player.create(s_or_c_or_o : char ; pseudo : string;host_or_map: string);
    begin
      inherited create;
        case s_or_c_or_o of
        'c' : begin
                game_type := 'c';
                pseudo_ := pseudo;
                host_ := host_or_map;
                myreseauennemis := c_res_ennemi.create;
        end;
        's' : begin
                game_type := 's';
                mymesh := c_mesh.create(host_or_map, game_type);
                pseudo_ := pseudo;
                myastar := C_Astar.create;
        end;
        'o' : begin
                game_type := 'o';
                mymesh := c_mesh.create(host_or_map, game_type);
                myastar := C_Astar.create;
        end;
      end;
      tiny_pas := c_sound.create('Sound\pastiny.wav');
      tiny_hit := c_sound.create('Sound\attaqueasus.wav');
      tiny_hitted := c_sound.create('Sound\attaqueennemi.wav');
      mychat := c_chat.create(myform._3D_device, 0, 0);
      map_name := host_or_map;
      is_loaded := false;
      init_obj_carac;
      gestion_catac;
      carac.vie.actuel := carac.vie.stuff;
      carac.niveau.actuel := 1;
      carac.armure.actuel := 200;
      dep := true;
      next_step := 10;
      myreseau := c_res_joueur.create;
      etage := 0;
      timer := c_timer.create;
      vie := 1000;
      attaque := C_timer.Create;
      attaque.init(3000);
    end;

  procedure c_player.gestion_catac;
  var
    i: Integer;
  begin
    for i := 0 to length(tab_contenu) - 1 do
      begin
        if tab_contenu[i].equip = true then
          begin
            if (tab_contenu[i]._type = 'Ram') and (carac.vitesse.emplacement_libre = 2) then
              begin
                carac.vitesse.stuff := carac.vitesse.init + carac.portee.stuff * 2 * tab_contenu[i].carac1;
                carac.vitesse.emplacement_libre := carac.vitesse.emplacement_libre - 1;
              end
            else
              if (tab_contenu[i]._type = 'Ram') and (carac.vitesse.emplacement_libre = 1) then
                begin
                  carac.vitesse.stuff := carac.vitesse.stuff +  tab_contenu[i].carac1;
                  carac.vitesse.emplacement_libre := carac.vitesse.emplacement_libre - 1;
                end
              else
                if (tab_contenu[i]._type = 'Processeur') and (carac.force.emplacement_libre = 2) then
                  begin
                    carac.force.stuff := carac.force.init + carac.portee.stuff * 2 * tab_contenu[i].carac1;
                    carac.force.emplacement_libre := carac.force.emplacement_libre - 1;
                  end
                else
                  if (tab_contenu[i]._type = 'Processeur') and (carac.force.emplacement_libre = 1) then
                    begin
                      carac.force.stuff := carac.force.stuff + tab_contenu[i].carac1;
                      carac.force.emplacement_libre := carac.force.emplacement_libre - 1;                    
                    end
                  else
                    if tab_contenu[i]._type = 'Carte graphique' then
                      carac.discretion.stuff := 10 + tab_contenu[i].carac1
                    else
                      if tab_contenu[i]._type = 'Disque dur' then
                        carac.taille.stuff := carac.taille.init + tab_contenu[i].carac1
                      else
                        if (tab_contenu[i]._type = 'Armes') and (carac.portee.emplacement_libre = 2) then
                          begin
                            carac.portee.stuff := carac.portee.init + carac.portee.stuff * 2 * tab_contenu[i].carac1;
                            carac.degats.stuff := carac.degats.init + carac.portee.stuff * 2 * tab_contenu[i].carac2;
                            carac.portee.emplacement_libre := carac.portee.emplacement_libre - 1;
                          end
                        else
                          if (tab_contenu[i]._type = 'Armes') and (carac.portee.emplacement_libre = 1) then
                            begin
                              carac.portee.stuff := carac.niveau.stuff + tab_contenu[i].carac1;
                              carac.degats.stuff := carac.niveau.stuff + tab_contenu[i].carac2;
                              carac.portee.emplacement_libre := carac.portee.emplacement_libre - 1;
                            end;
          end;

      end;
  end;

  procedure c_player.update_equip_obj(posi: Integer);
  begin
    tab_contenu[posi].equip := true;
    if (tab_contenu[posi]._type = 'Ram') and (carac.vitesse.emplacement_libre = 2) then
      begin
        carac.vitesse.stuff := carac.vitesse.init + carac.niveau.stuff * 2 * tab_contenu[posi].carac1;
        carac.vitesse.emplacement_libre := carac.vitesse.emplacement_libre - 1;
      end
    else
      if (tab_contenu[posi]._type = 'Ram') and (carac.vitesse.emplacement_libre = 1) then
        begin
          carac.vitesse.stuff := carac.vitesse.stuff +  tab_contenu[posi].carac1;
          carac.vitesse.emplacement_libre := carac.vitesse.emplacement_libre - 1;
        end
      else
        if (tab_contenu[posi]._type = 'Processeur') and (carac.force.emplacement_libre = 2) then
          begin
            carac.force.stuff := carac.force.init + carac.niveau.stuff * 2 * tab_contenu[posi].carac1;
            carac.force.emplacement_libre := carac.force.emplacement_libre - 1;
          end
        else
          if (tab_contenu[posi]._type = 'Processeur') and (carac.force.emplacement_libre = 1) then
            begin
              carac.force.stuff := carac.force.stuff + tab_contenu[posi].carac1;
              carac.force.emplacement_libre := carac.force.emplacement_libre - 1;                    
            end
          else
            if tab_contenu[posi]._type = 'Carte graphique' then
              carac.discretion.stuff := 10 + tab_contenu[posi].carac1
            else
              if tab_contenu[posi]._type = 'Disque dur' then
                carac.taille.stuff := carac.taille.init + tab_contenu[posi].carac1
              else
                if (tab_contenu[posi]._type = 'Armes') and (carac.portee.emplacement_libre = 2) then
                  begin
                    carac.portee.stuff := carac.portee.init + carac.portee.stuff * 2 * tab_contenu[posi].carac1;
                    carac.degats.stuff := carac.degats.init + carac.portee.stuff * 2 * tab_contenu[posi].carac2;
                    carac.portee.emplacement_libre := carac.portee.emplacement_libre - 1;
                  end
                else
                  if (tab_contenu[posi]._type = 'Armes') and (carac.portee.emplacement_libre = 1) then
                    begin
                      carac.portee.stuff := carac.portee.stuff + tab_contenu[posi].carac1;
                      carac.degats.stuff := carac.degats.stuff + tab_contenu[posi].carac2;
                      carac.portee.emplacement_libre := carac.portee.emplacement_libre - 1;
                    end;
    end;


  procedure c_player.update_desequip_obj(posi: Integer);
  begin
    if (tab_contenu[posi]._type = 'Ram') and (carac.vitesse.emplacement_libre = 1) then
      begin
        carac.vitesse.stuff := carac.vitesse.init;
        carac.vitesse.emplacement_libre := carac.vitesse.emplacement_libre + 1;
      end
    else
      if (tab_contenu[posi]._type = 'Ram') and (carac.vitesse.emplacement_libre = 0) then
        begin
          carac.vitesse.stuff := carac.vitesse.stuff - tab_contenu[posi].carac1;
          carac.vitesse.emplacement_libre := carac.vitesse.emplacement_libre + 1;
        end
      else
        if (tab_contenu[posi]._type = 'Processeur') and (carac.force.emplacement_libre = 1) then
          begin
            carac.force.stuff := carac.force.init;
            carac.force.emplacement_libre := carac.force.emplacement_libre + 1;
          end
        else
          if (tab_contenu[posi]._type = 'Processeur') and (carac.force.emplacement_libre = 0) then
            begin
              carac.force.stuff := carac.force.stuff - tab_contenu[posi].carac1;
              carac.force.emplacement_libre := carac.force.emplacement_libre + 1;                    
            end
          else
            if tab_contenu[posi]._type = 'Carte graphique' then
              carac.discretion.stuff := 10 + tab_contenu[posi].carac1
            else
              if tab_contenu[posi]._type = 'Disque dur' then
                carac.taille.stuff := carac.taille.init + tab_contenu[posi].carac1
              else
                if (tab_contenu[posi]._type = 'Armes') and (carac.portee.emplacement_libre = 1) then
                  begin
                    carac.portee.stuff := carac.portee.init;
                    carac.degats.stuff := carac.degats.init;
                    carac.portee.emplacement_libre := carac.portee.emplacement_libre + 1;
                  end
                else
                  if (tab_contenu[posi]._type = 'Armes') and (carac.portee.emplacement_libre = 0) then
                    begin
                      carac.portee.stuff := carac.portee.init - tab_contenu[posi].carac1;
                      carac.degats.stuff := carac.degats.init - tab_contenu[posi].carac2;
                      carac.portee.emplacement_libre := carac.portee.emplacement_libre + 1;
                    end;
    tab_contenu[posi].equip := false;
    tab_contenu[posi].g_d := ' ';   
  end;


//modif

  procedure c_player.init_obj_carac;
  begin
      SetLength(tab_contenu, 8);
      tab_contenu[0].nom := 'or';
      tab_contenu[0]._type := 'Argent';
      tab_contenu[0].quantite := 42;
      tab_contenu[0].equip := false;
      tab_contenu[1].nom := 'ram128';
      tab_contenu[1]._type := 'Ram';
      tab_contenu[1].icone := 'asus menu\icone\ram 128.png';
      tab_contenu[1].carac1 := 4;
      tab_contenu[1].quantite := 1;
      tab_contenu[1].equip := true;
      tab_contenu[1].g_d := 'd';
      tab_contenu[2].nom := 'Amd turion';
      tab_contenu[2]._type := 'Processeur';
      tab_contenu[2].icone := 'asus menu\icone\amd1.png';
      tab_contenu[2].carac1 := 5;
      tab_contenu[2].quantite := 1;
      tab_contenu[2].equip := true;
      tab_contenu[2].g_d := 'd';
      tab_contenu[3].nom := 'Maxtor 10';
      tab_contenu[3]._type := 'Disque dur';
      tab_contenu[3].icone := 'asus menu\icone\dd100.png';
      tab_contenu[3].carac1 := 6;
      tab_contenu[3].quantite := 1;
      tab_contenu[3].equip := true;;
      tab_contenu[3].g_d := 'd';
      tab_contenu[4].nom := 'FX 4200';
      tab_contenu[4]._type := 'Carte graphique';
      tab_contenu[4].icone := 'asus menu\icone\g1.png';
      tab_contenu[4].carac1 := 5;
      tab_contenu[4].quantite := 1;
      tab_contenu[4].equip := true;
      tab_contenu[4].g_d := 'd';
      tab_contenu[5].nom := 'Gourdin';
      tab_contenu[5]._type := 'Armes';
      tab_contenu[5].icone := 'asus menu\icone\arme1.png';
      tab_contenu[5].carac1 := 2;
      tab_contenu[5].carac2 := 10;
      tab_contenu[5].quantite := 1;
      tab_contenu[5].equip := true;
      tab_contenu[5].g_d := 'd';
      tab_contenu[6].nom := 'Ram256';
      tab_contenu[6]._type := 'Ram';
      tab_contenu[6].icone := 'asus menu\icone\ram 256.png';
      tab_contenu[6].carac1 := 6;
      tab_contenu[6].quantite := 1;
      tab_contenu[6].equip := false;
      tab_contenu[7].nom := 'X1300';
      tab_contenu[7]._type := 'Carte graphique';
      tab_contenu[7].icone := 'asus menu\icone\g2.png';
      tab_contenu[7].carac1 := 6;
      tab_contenu[7].quantite := 1;
      tab_contenu[7].equip := false;

      carac.niveau.init := 1;
      carac.vie.init := 100;
      carac.vie.stuff := 100;
      carac.xp.init := 100;
      carac.xp.actuel := 0;
      carac.xp.stuff := 100;
      carac.force.init := 90;
      carac.force.stuff := 90;
      carac.discretion.init := 5;
      carac.discretion.stuff := 5;
      carac.degats.init := 5;
      carac.degats.stuff := 5;
      carac.portee.init := 1;
      carac.portee.stuff := 1;
      carac.taille.init := 4;
      carac.taille.stuff := 4;
      carac.armure.init := 10;
      carac.armure.stuff:= 10;
      carac.vitesse.init := 10;
      carac.vitesse.stuff := 10;
      carac.vitesse.emplacement_libre := 2;
      carac.force.emplacement_libre := 2;
      carac.portee.emplacement_libre := 2;
  end;

  procedure c_player.load_player(dev_: Device);
    begin
      if game_type <> 'c' then
        etage_actif := mymesh.dep_eta.etage;
      player_mesh := Mesh.FromFile('meshes\joueur.x', MeshFlags.SystemMemory, dev_);
      texture_titou := TextureLoader.FromFile(dev_, 'meshes\titou.png');
      texture_clad := TextureLoader.FromFile(dev_, 'meshes\clad.png');
      texture_xoy := TextureLoader.FromFile(dev_, 'meshes\xoy.png');
      texture_mouton := TextureLoader.FromFile(dev_, 'meshes\mouton.png');

      if game_type <> 'c' then
        mymesh.loader_mesh(dev_, mymesh.dep_eta.etage);
      mychat.show(true);
    end;

  procedure c_player.get_coord(var x_: Integer; var y_: Integer);
    begin
      x_ := player_x;
      y_ := player_y;
    end;

  procedure c_player.render_player(form_dev : Device);
    begin
    if is_loaded then
      begin
        form_dev.Transform.World :=
                        form_dev.Transform.World.RotationZ(math.pi /2) *
                        form_dev.Transform.World.RotationX(-math.pi / 2) *
                        form_dev.Transform.World.Translation(player_x + 0.5, 0, player_y + 0.5);

        if mymenu.player_name = 'titou' then
          form_dev.SetTexture(0, texture_titou)
          else
          if mymenu.player_name = 'clad' then
            form_dev.SetTexture(0, texture_clad)
            else
            if mymenu.player_name = 'xoy' then
              form_dev.SetTexture(0, texture_xoy)
              else
              form_dev.SetTexture(0, texture_mouton);


        next_step := next_step - 1;
        if next_step <= 0 then
          begin
            next_step := 10;
            player_avance;
          end;

      end
    else
      begin
        is_loaded := true;
        load_player(form_dev);
        player_x := mymesh.dep_eta.x;
        player_y := mymesh.dep_eta.y;
      end;
    end;

  procedure c_player.calcul_astar(to_x: Integer; to_y: Integer);
    begin
      myastar.init_sg(player_x, player_y, to_x, to_y, mymesh.dep_eta.etage ,mymesh.taillex,mymesh.tailley, mymesh.map2);
    end;

  function c_player.get_x;
    begin
      Result := player_x;
    end;

  function c_player.get_y;
    begin
      Result := player_y;
    end;

  procedure c_player.player_avance;
  var
    tmp : T_Move;
    x_, y_ : integer;
    begin
      x_ := player_x;
      y_ := player_y;
      tmp := myastar.retourne(player_x,player_y);
      player_x := tmp.x;
      player_y := tmp.y;
      if ((x_ <> player_x) or (y_ <> player_y)) then
        tiny_pas.play;
      if (length(myastar.chemin) = 1) and (dep = false) then
        arrive := true;
      if (game_type = 's') or (game_type = 'c') and ((x_ <> player_x) or (y_ <> player_y)) then
        begin
          if game_type = 's' then
              clientorserveur.Send_newpos_allclients(IntToStr(x_), IntToStr(y_), IntToStr(etage), IntToStr(player_x), inttostr(player_y), IntToStr(etage))
            else
              clientorserveur.new_posclient(IntToStr(x_), IntToStr(y_), IntToStr(etage),IntToStr(player_x), inttostr(player_y), IntToStr(etage));
        end;
    end;

  procedure c_player.send_message(msg_: string);
    begin
      case game_type of
        'o' : mychat.add_text(msg_);
        's' : begin
          clientorserveur.Send_msg_allclients(pseudo_ + ' : ' + msg_);
        end;
        'c' : begin
          clientorserveur.msg_client(pseudo_ + ' : ' + msg_);
        end;
      end;
    end;



end.
